added Feb 2001 SDK
[windows-sources.git] / shared source / sscli20 / jscript / engine / stackframe.cs
blob4b4c9635b0676feb5616bbac14edc23bb76349a8
1 // ==++==
2 //
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 //
14 // ==--==
16 namespace Microsoft.JScript {
18 /*
19 A stack frame is used to avoid allocating the name lookup hash table until it is actually needed.
21 Rather than allocating the hash table directly and then duplicating code that already resides in JSObject and FunctionScope,
22 a FunctionScope is allocated and populated whenever the hashtable is needed for a name lookup.
25 using Microsoft.JScript.Vsa;
26 using System;
27 using System.Reflection;
28 using System.Collections;
29 using System.Diagnostics;
31 public sealed class StackFrame : ScriptObject, IActivationObject{
32 internal ArgumentsObject caller_arguments;
33 private JSLocalField[] fields;
34 public Object[] localVars;
35 private FunctionScope nestedFunctionScope;
36 internal Object thisObject;
37 public Object closureInstance;
39 internal StackFrame(ScriptObject parent, JSLocalField[] fields, Object[] local_vars, Object thisObject)
40 : base(parent) {
41 this.caller_arguments = null;
42 this.fields = fields;
43 this.localVars = local_vars;
44 this.nestedFunctionScope = null;
45 this.thisObject = thisObject;
46 if (parent is StackFrame)
47 this.closureInstance = ((StackFrame)parent).closureInstance;
48 else if (parent is JSObject)
49 this.closureInstance = parent;
50 else
51 this.closureInstance = null;
54 internal JSVariableField AddNewField(String name, Object value, FieldAttributes attributeFlags){
55 this.AllocateFunctionScope();
56 return this.nestedFunctionScope.AddNewField(name, value, attributeFlags);
59 private void AllocateFunctionScope(){
60 if (this.nestedFunctionScope != null)
61 return;
62 this.nestedFunctionScope = new FunctionScope(this.parent);
63 if (this.fields != null)
64 for (int i = 0, n = this.fields.Length; i < n; i++)
65 this.nestedFunctionScope.AddOuterScopeField(this.fields[i].Name, this.fields[i]);
68 public Object GetDefaultThisObject(){
69 ScriptObject parent = this.GetParent();
70 IActivationObject iob = parent as IActivationObject;
71 if (iob != null) return iob.GetDefaultThisObject();
72 return parent;
75 public FieldInfo GetField(String name, int lexLevel){
76 return null;
79 public GlobalScope GetGlobalScope(){
80 return ((IActivationObject)this.GetParent()).GetGlobalScope();
83 FieldInfo IActivationObject.GetLocalField(String name){
84 this.AllocateFunctionScope();
85 return this.nestedFunctionScope.GetLocalField(name);
88 public override MemberInfo[] GetMember(String name, BindingFlags bindingAttr){
89 this.AllocateFunctionScope();
90 return this.nestedFunctionScope.GetMember(name, bindingAttr);
93 public override MemberInfo[] GetMembers(BindingFlags bindingAttr){
94 this.AllocateFunctionScope();
95 return this.nestedFunctionScope.GetMembers(bindingAttr);
98 internal override void GetPropertyEnumerator(ArrayList enums, ArrayList objects){
99 throw new JScriptException(JSError.InternalError);
102 #if !DEBUG
103 [DebuggerStepThroughAttribute]
104 [DebuggerHiddenAttribute]
105 #endif
106 internal override Object GetMemberValue(String name){
107 this.AllocateFunctionScope();
108 return this.nestedFunctionScope.GetMemberValue(name);
111 #if !DEBUG
112 [DebuggerStepThroughAttribute]
113 [DebuggerHiddenAttribute]
114 #endif
115 public Object GetMemberValue(String name, int lexlevel){
116 if (lexlevel <= 0)
117 return Missing.Value;
118 if (this.nestedFunctionScope != null)
119 return this.nestedFunctionScope.GetMemberValue(name, lexlevel);
120 else
121 return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel-1);
124 public static void PushStackFrameForStaticMethod(RuntimeTypeHandle thisclass, JSLocalField[] fields, VsaEngine engine){
125 PushStackFrameForMethod(Type.GetTypeFromHandle(thisclass), fields, engine);
128 public static void PushStackFrameForMethod(Object thisob, JSLocalField[] fields, VsaEngine engine){
129 Globals globals = engine.Globals;
130 IActivationObject top = (IActivationObject)globals.ScopeStack.Peek();
131 String currentNamespace = thisob.GetType().Namespace;
132 WithObject wob = null;
133 if (currentNamespace != null && currentNamespace.Length > 0){
134 wob = new WithObject(top.GetGlobalScope(), new WrappedNamespace(currentNamespace, engine));
135 wob.isKnownAtCompileTime = true; //For use by an eval inside this method
136 wob = new WithObject(wob, thisob);
137 }else
138 wob = new WithObject(top.GetGlobalScope(), thisob);
139 wob.isKnownAtCompileTime = true;
140 StackFrame sf = new StackFrame(wob, fields, new Object[fields.Length], thisob);
141 sf.closureInstance = thisob;
142 globals.ScopeStack.GuardedPush(sf);
145 #if !DEBUG
146 [DebuggerStepThroughAttribute]
147 [DebuggerHiddenAttribute]
148 #endif
149 internal override void SetMemberValue(String name, Object value){
150 this.AllocateFunctionScope();
151 this.nestedFunctionScope.SetMemberValue(name, value, this);